package com.example.androidautoproject.service

import android.accessibilityservice.GestureDescription
import android.database.ContentObserver
import android.graphics.Path
import android.graphics.Rect
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.provider.MediaStore
import android.text.TextUtils
import android.util.Log
import android.view.accessibility.AccessibilityEvent
import android.view.accessibility.AccessibilityNodeInfo
import android.view.accessibility.AccessibilityWindowInfo
import com.example.androidautoproject.utils.AdParam
import com.example.androidautoproject.utils.AutoScript
import com.example.androidautoproject.utils.AutoScript.click_element
import com.example.androidautoproject.utils.LogWrapper
import com.example.androidautoproject.utils.ScreenshotUtil
import com.ven.assists.AssistsCore
import com.ven.assists.AssistsCore.getBoundsInScreen
import com.ven.assists.AssistsCore.isVisible
import com.ven.assists.service.AssistsService
import org.json.JSONArray
import org.json.JSONException
import org.json.JSONObject
import java.io.File
import java.util.IdentityHashMap
import java.util.Locale
import kotlin.random.Random


// 修改后的 MainService.kt
class MainService: AssistsService() {
    // 内容观察者
    private var screenshotObserver: ContentObserver? = null

    // 截图监听器
    private val screenshotListeners = mutableListOf<(String?) -> Unit>()
    private val listenersLock = Any()

    companion object {
        private const val TAG = "ServerProject"
        var instance: MainService? = null
        const val SCREENSHOT_DELAY = 3000L
    }

    override fun onServiceConnected() {
        super.onServiceConnected()
        instance = this
        // 注册截图观察者
        registerScreenshotObserver()
    }

    override fun onDestroy() {
        super.onDestroy()
        instance = null
        // 取消注册截图观察者
        unregisterScreenshotObserver()
    }

    override fun onAccessibilityEvent(event: AccessibilityEvent) {
        super.onAccessibilityEvent(event)
        when (event.eventType) {
            AccessibilityEvent.TYPE_WINDOW_STATE_CHANGED -> {
                // Log.d(TAG, "窗口状态变化")
                if(event.packageName != "com.example.androidautoproject" && event.className != "android.view.ViewGroup"){
                    AdParam.className = event.className.toString()
                    AdParam.packageName1 = event.packageName.toString()
                    Handler().postDelayed({
                        val rootNode = rootInActiveWindow
                        if (rootNode != null) {
                            AdParam.packageName = rootNode.packageName.toString()
                            AdParam.className1 = rootNode.className.toString()
                            Log.d(AdParam.currentTag, "包名: ${AdParam.packageName} 类名：${AdParam.className}")
                            LogWrapper.logAppend("包名: ${AdParam.packageName} 类名：${AdParam.className}")
                            rootNode.recycle()
                        }
                    }, 500)
                }
            }
            AccessibilityEvent.TYPE_WINDOW_CONTENT_CHANGED -> {
                Log.d("adProject", "窗口内容变化")
                Log.d("adProject", "包名: ${event.packageName} ${event.className}")
            }
            AccessibilityEvent.TYPE_VIEW_SCROLLED -> {
                // 可以监听滚动事件
                Log.d("adProject", "监听滚动事件")
            }
            else -> {
                Log.d(TAG, "其他类型事件: ${event.eventType}")
            }
        }
    }

    fun close_app(){
        Thread.sleep(2000)
        AssistsCore.recentApps()
        Thread.sleep(2000)
        var ran = Random.nextDouble(-5.0, 5.0)
        gestureAction(
            floatArrayOf((531f + ran).toFloat(), (1533f + ran).toFloat()),
            floatArrayOf((564f + ran).toFloat(), (238f + ran).toFloat()),
            500L,
            1000L)
        Thread.sleep(5000)
    }

    fun close_app1(){
        Thread.sleep(2000)
        AssistsCore.recentApps()
        Thread.sleep(2000)
        var ran = Random.nextDouble(-5.0, 5.0)
        gestureAction(
            floatArrayOf((531f + ran).toFloat(), (1033f + ran).toFloat()),
            floatArrayOf((531f + ran).toFloat(), (1033f + ran).toFloat()),
            0,
            10L)
        Thread.sleep(5000)
    }

    fun gestureAction(
        startLocation: FloatArray,
        endLocation: FloatArray,
        startTime: Long,
        duration: Long,
    ) {
        val path = Path()
        path.moveTo(startLocation[0], startLocation[1])
        path.lineTo(endLocation[0], endLocation[1])
        val builder = GestureDescription.Builder()
        val strokeDescription = GestureDescription.StrokeDescription(path, startTime, duration)
        val gestureDescription = builder.addStroke(strokeDescription).build()
        // 执行手势
        dispatchGesture(gestureDescription, object : GestureResultCallback() {
            override fun onCompleted(gestureDescription: GestureDescription?) {
                super.onCompleted(gestureDescription)
            }

            override fun onCancelled(gestureDescription: GestureDescription?) {
                super.onCancelled(gestureDescription)
            }
        }, null)
    }

    // 截取屏幕
    fun takeScreenshot(callback: (String?) -> Unit) {
        // 添加回调到监听器列表
        synchronized(listenersLock) {
            screenshotListeners.add(callback)
            Log.d(TAG, "Added listener, total: ${screenshotListeners.size}")
        }
        val success = performGlobalAction(GLOBAL_ACTION_TAKE_SCREENSHOT)
    }

    // 注册内容观察者监听截图
    private fun registerScreenshotObserver() {
        val contentResolver = applicationContext.contentResolver
        val screenshotUri = MediaStore.Images.Media.EXTERNAL_CONTENT_URI

        screenshotObserver = object : ContentObserver(Handler(Looper.getMainLooper())) {
            override fun onChange(selfChange: Boolean, uri: Uri?) {
                super.onChange(selfChange, uri)
                if (uri != null) {
                    Log.d(TAG, "Media store changed: $uri")
                    handleMediaChange()
                }
            }
        }

        contentResolver.registerContentObserver(screenshotUri, true, screenshotObserver!!)
        Log.d(TAG, "Registered screenshot observer")
    }

    // 处理媒体库变化
    private fun handleMediaChange() {
        Log.d(TAG, "Handling media change")

        // 延迟一段时间确保文件完全写入
        Handler(Looper.getMainLooper()).postDelayed({
            val screenshot = getLatestScreenshot()
            ScreenshotUtil.screenshot = screenshot
            ScreenshotUtil.screenshotPath = screenshot?.absolutePath
            if (screenshot != null && screenshot.exists()) {
                Log.d(TAG, "Found new screenshot: ${screenshot.absolutePath}")

                // 通知所有监听器
                synchronized(listenersLock) {
                    if (screenshotListeners.isNotEmpty()) {
                        Log.d(TAG, "Notifying ${screenshotListeners.size} listeners")
                        val listeners = ArrayList(screenshotListeners)
                        screenshotListeners.clear()

                        // 在后台线程通知监听器
                        Thread {
                            for (listener in listeners) {
                                listener(screenshot.absolutePath)
                            }
                        }.start()
                    } else {
                        Log.d(TAG, "No listeners to notify")
                    }
                }
            } else {
                Log.d(TAG, "No valid screenshot found")
            }
        }, 1000) // 延迟1秒确保文件写入完成
    }

    // 获取最新的截图文件
    private fun getLatestScreenshot(): File? {
        try {
            // 优先使用 MediaStore API 查询截图
            val projection = arrayOf(
                MediaStore.Images.ImageColumns._ID,
                MediaStore.Images.ImageColumns.DATA,
                MediaStore.Images.ImageColumns.DATE_ADDED,
                MediaStore.Images.ImageColumns.DISPLAY_NAME
            )

            val sortOrder = "${MediaStore.Images.ImageColumns.DATE_ADDED} DESC"

            // 查询截图文件
            val cursor = contentResolver.query(
                MediaStore.Images.Media.EXTERNAL_CONTENT_URI,
                projection,
                "${MediaStore.Images.ImageColumns.DISPLAY_NAME} LIKE ? OR ${MediaStore.Images.ImageColumns.DISPLAY_NAME} LIKE ?",
                arrayOf("Screenshot%", "screenshot%"),
                sortOrder
            )

            cursor?.use {
                Log.e(TAG, "getLatestScreenshot1")
                if (it.moveToFirst()) {
                    Log.e(TAG, "getLatestScreenshot2")
                    val dataIndex = it.getColumnIndexOrThrow(MediaStore.Images.ImageColumns.DATA)
                    val filePath = it.getString(dataIndex)
                    val file = File(filePath)

                    // 检查文件是否存在且是最近创建的（15秒内）
                    if (file.exists() && System.currentTimeMillis() - file.lastModified() < 15000) {
                        Log.d(TAG, "Found recent screenshot via MediaStore: ${file.absolutePath}")
                        return file
                    } else {
                        Log.d(TAG, "Screenshot file not recent or doesn't exist: ${file.absolutePath}")
                    }
                } else {
                    Log.d(TAG, "No screenshots found via MediaStore")
                }
            }
        } catch (e: Exception) {
            Log.e(TAG, "Error getting latest screenshot: ${e.message}")
        }

        return null
    }


    private fun unregisterScreenshotObserver() {
        screenshotObserver?.let {
            contentResolver.unregisterContentObserver(it)
            screenshotObserver = null
            Log.d(TAG, "Screenshot observer unregistered")
        }
    }

    fun getRootNodeInActiveWindow(): AccessibilityNodeInfo? {
        // 直接使用 getRootInActiveWindow() 方法
        val rootNode = rootInActiveWindow
        if (rootNode == null) {
            Log.w("MyAccessibilityService", "无法获取 rootInActiveWindow, 为 null")
            return null
        }
        return rootNode
    }

    // 将节点信息转换为JSON格式
    @Throws(JSONException::class)
    fun nodeToJson(node: AccessibilityNodeInfo?): JSONObject? {
        if (node == null) return null
        val jsonNode = JSONObject()
        // 添加基本属性
        if (node.text != null) {
            jsonNode.put("text", node.text.toString())
        }
        if (node.className != null) {
            jsonNode.put("className", node.className.toString())
        }
        if (node.packageName != null) {
            jsonNode.put("packageName", node.packageName.toString())
        }
        if (node.contentDescription != null) {
            jsonNode.put("contentDescription", node.contentDescription.toString())
        }
        if (node.viewIdResourceName != null) {
            jsonNode.put("viewId", node.viewIdResourceName)
        }
        jsonNode.put("clickable", node.isClickable)
        jsonNode.put("isVisibleToUser", node.isVisibleToUser)
        jsonNode.put("focusable", node.isFocusable)
        jsonNode.put("checked", node.isChecked)
        jsonNode.put("enabled", node.isEnabled)
        jsonNode.put("selected", node.isSelected)
        jsonNode.put("longClickable", node.isLongClickable)
        jsonNode.put("password", node.isPassword)
        jsonNode.put("scrollable", node.isScrollable)
        // 添加屏幕位置信息
        val bounds = Rect()
        node.getBoundsInScreen(bounds)
        val boundsJson = JSONObject()
        boundsJson.put("left", bounds.left)
        boundsJson.put("top", bounds.top)
        boundsJson.put("right", bounds.right)
        boundsJson.put("bottom", bounds.bottom)
        boundsJson.put("width", bounds.width())
        boundsJson.put("height", bounds.height())
        jsonNode.put("bounds", boundsJson)
        return jsonNode
    }

    fun find_and_click_element_by_text(text:String, isClick:Boolean):Boolean{
        var found = false
        for (window in windows) {
            if (window.type == AccessibilityWindowInfo.TYPE_APPLICATION) {
                val root = window.root
                if (root != null) {
                    // 在这里遍历这个root节点
                    try {
                        found = findAndClickNodesWithText(root, text, isClick) || found
                    } finally {
                        root.recycle() // 确保根节点被回收
                    }
                }
            }
        }
        return found
    }

    private fun findAndClickNodesWithText(
        node: AccessibilityNodeInfo,
        text: String,
        isClick: Boolean
    ): Boolean {
        // 检查当前节点是否包含目标文本

        if (!TextUtils.isEmpty(node.text) && node.text.indexOf(text) >= 0) {
            if (isClick) {
                val bounds = Rect()
                node.getBoundsInScreen(bounds)
                val randomX = bounds.left + Random.nextInt(bounds.width())
                val randomY = bounds.top + Random.nextInt(bounds.height())
                gestureAction(
                    floatArrayOf((randomX).toFloat(), (randomY).toFloat()),
                    floatArrayOf((randomX).toFloat(), (randomY).toFloat()),
                    0,
                    10L
                )
            }
            return true
        }
        // 递归检查子节点
        for (i in 0 until node.childCount) {
            val child = node.getChild(i)
            if (child != null) {
                try {
                    val found = findAndClickNodesWithText(child, text, isClick)
                    if (found) {
                        return true
                    }
                } finally {
                    // 重要：回收每个获取的子节点
                    child.recycle()
                }
            }
        }
        return false
    }

    // 根据文本查找节点
    fun findNodesByText(text: String): List<AccessibilityNodeInfo> {
        val result: MutableList<AccessibilityNodeInfo> = ArrayList()
        for (window in windows) {
            LogWrapper.logAppend("window type ${window.type}")
            if (window.type == AccessibilityWindowInfo.TYPE_APPLICATION || window.type == AccessibilityWindowInfo.TYPE_SYSTEM) {
                val root = window.root
                if (root != null) {
                    // 在这里遍历这个root节点
                    try {
                        findNodesWithText(root, text, result)
                    } finally {
                        // 重要：根节点也需要回收，但只在它不在结果集中时回收
                        if (!result.contains(root)) {
                            root.recycle()
                        }
                    }

                }
            }
        }
        return result
    }

    private fun findNodesWithText(
        node: AccessibilityNodeInfo?,
        text: String,
        result: MutableList<AccessibilityNodeInfo>
    ) {
        if (node == null) return
        // 检查当前节点是否包含目标文本
        if (node.text != null && node.text.toString().lowercase(Locale.getDefault())
                .contains(text.lowercase(Locale.getDefault()))
        ) {
            result.add(node)
        }
        // 递归检查子节点
        for (i in 0 until node.childCount) {
            val child = node.getChild(i)
            if (child != null) {
                findNodesWithText(child, text, result)
                // 重要：只有未被添加到结果集的子节点才需要回收
                if (!result.contains(child)) {
                    child.recycle()
                }
            }
        }
    }

    // 查找节点并返回JSON格式结果
    fun findNodesByTextAsJson(text: String): JSONArray {
        val nodes = findNodesByText(text)
        val result = JSONArray()

        for (node in nodes) {
            try {
                result.put(nodeToJson(node))
            } catch (e: JSONException) {
                Log.e(TAG, "转换节点到JSON时出错", e)
            } finally {
                // 回收节点
                node?.recycle()
            }
        }

        return result
    }
}